package face.pay.api.payter.channel.paytype.alilpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import com.face.pay.AliPayConfig;
import face.pay.api.alipay.param.TradeParam;
import face.pay.api.payter.channel.paytype.alilpay.api.ApiAliOrderQuery;
import face.pay.constant.OrderStatus;
import face.pay.constant.OrderType;
import face.pay.constant.PayType;
import face.pay.entity.EnterpriseInfo;
import face.pay.entity.OemInfo;
import face.pay.entity.OrderInfo;
import face.pay.entity.StoreInfo;
import face.pay.api.payter.channel.paytype.AbstractPayType;
import face.pay.util.MathUtil;
import face.pay.util.ResultMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 支付宝刷脸支付
 */
@Component
@Slf4j
public class AliQrPay extends AbstractPayType {

    @Autowired
    ApiAliOrderQuery apiAliOrderQuery;

    @Override
    public ResultMessage pay(JSONObject json) {

        log.info("支付宝付款>扫码支付订单:" + json.toJSONString());

        try {

            Integer terminalId = json.getInteger("terminalId");

            Long total_fee   = json.getLong("total_fee")==null?new Long(0):json.getLong("total_fee");

            String authCode     = json.getString("auth_code");

            String out_trade_no = json.getString("out_trade_no");
            String channelCode  =  json.getString("channelCode");

            String codeType  =  json.getString("codeType");


            Long orderId = Long.valueOf(out_trade_no);

            log.info("查找订单: orderId" + orderId);

            OrderInfo orderInfo = this.orderInfoDao.getById(orderId);

            if (orderInfo != null) {

                log.info("订单信息: " + orderInfo.toString());

                if (!new Integer(0).equals(orderInfo.getStatus())) {
                    log.info("订单已经被处理，重新发起支付请求 ");
                    return ResultMessage.createFail("订单已经被处理，重新发起支付请求");
                }
                Boolean safe = this.paySafe(orderInfo, terminalId, total_fee);

                if (!safe) {
                    log.info("交易信息不正确，中断支付");
                    return ResultMessage.createFail("交易信息不正确，中断支付");
                } else {

                    Integer oemId = orderInfo.getOemId();

                    Integer storeId = orderInfo.getStoreId();

                    OemInfo oemInfo = this.oemInfoDao.getOemInfoById(oemId);

                    AliPayConfig aliConfig =  this.iWxPayConfigServer.getAliConfig(oemId);

                    if(aliConfig.validate()){

                        String type = oemInfo.getType();

                        StoreInfo storeInfo = this.storeInfoDao.getById(storeId);

                        EnterpriseInfo enterpriseInfo = this.enterpriseInfoDao.getById(storeInfo.getEnterpriseId());

                        String aliUserId = enterpriseInfo.getAliUserId();

                        String app_auth_token = enterpriseInfo.getAliToken();

                        if (StringUtils.isBlank(aliUserId) && StringUtils.isBlank(app_auth_token)) {
                            log.info("支付宝用户身份信息错误");
                            return ResultMessage.createFail("支付宝商家用户身份信息错误");
                        }

                        String body = storeInfo.getName() + "-线下支付";

                        Double money =     MathUtil.transForMoney(new Long(total_fee));

                        AlipayClient alipayClient = new DefaultAlipayClient(
                                "https://openapi.alipay.com/gateway.do", aliConfig.getAppid(), aliConfig.getAppKey(), "json", "GBK", aliConfig.getAliPublicKey(), "RSA2");


                        AlipayTradePayRequest alipayTradePayRequest = new AlipayTradePayRequest();

                        TradeParam tradepayParam = new TradeParam();

                        tradepayParam.setOut_trade_no(out_trade_no);

                        tradepayParam.setAuth_code(authCode);
                        tradepayParam.setScene("bar_code");
                        tradepayParam.setSeller_id(aliUserId);

                        tradepayParam.setSubject(body);

                        tradepayParam.setStore_id(String.valueOf(storeId));
                        tradepayParam.setTimeout_express("1m");
                        tradepayParam.setTotal_amount(money.toString());


                        Map<String,String> extend_params =  new HashMap<String,String>();
                        extend_params.put("sys_service_provider_id",aliConfig.getAliProviderId());
                        tradepayParam.setExtend_params(extend_params);

                        String jsonParam= JSON.toJSONString(tradepayParam);

                        alipayTradePayRequest.setBizContent(jsonParam);
                        log.info("支付宝扫码支付>> 参数");
                        log.info(jsonParam);
                        alipayTradePayRequest.putOtherTextParam("app_auth_token",enterpriseInfo.getAliToken());

                        AlipayTradePayResponse response = alipayClient.execute(alipayTradePayRequest);
                        log.info("支付宝扫码支付<<返回");
                        log.info(JSON.toJSONString(response));

                        String code = response.getCode();
                        String error = response.getMsg();

                        if("10000".equals(code) || "10003".equals(code)){

                        if(response.isSuccess()){

                                log.info("支付请求成功");
                                /**
                                 * 订单已经被支付默认
                                 */


                                String buyer_user_id = response.getBuyerUserId();
                                String tradeNo = response.getTradeNo();

                                orderInfo.setPayUserSign(buyer_user_id);
                                orderInfo.setPayCode(authCode);
                                orderInfo.setChannelCode(channelCode);
                                orderInfo.setType(OrderType.ALIPAY);
                                orderInfo.setProfitSign(0);
                                orderInfo.setPayType(PayType.SQR);

                                orderInfo.setTradeNo(tradeNo);

                                orderInfo.setSharing(0);
                                orderInfo.setScene(0);
                                orderInfo.setActFee(total_fee);
                                orderInfo.setServiceFee(new Long(0));
                                orderInfo.setActInnerFee(total_fee);

                                this.orderInfoDao.updatePayInfo(orderInfo);

                                apiAliOrderQuery.orderStatusCheck(orderInfo,aliConfig,oemInfo);

                                Map<String,Object> resultMap =  new HashMap<String,Object>();
                                resultMap.put("type",OrderType.ALIPAY);
                                resultMap.put("payType",PayType.SQR);
                                resultMap.put("out_trade_no",out_trade_no);

                            /**
                             *   监控订单状态 如果 支付成功则立即返回
                             *   未支付 最多25秒立即返回
                             *
                             */
                            Integer [] timeList =  new Integer[]{ 1,2,2,3,3,5};
                            String orderStatus = OrderStatus.NOTPAY;
                            String message = "订单暂未支付，手机端确认支付结果";
                             for(Integer i=0;i<timeList.length;i++){

                                log.info("检查订单状态 第"+i+"次");
                                Long time = Long.valueOf(timeList[i]*1000);
                                Thread.sleep(time);

                                OrderInfo info = this.orderInfoDao.getById(orderId);

                                Integer status = info.getStatus();
                                message = info.getMessage();

                                 orderStatus =    OrderStatus.getStatus(status);
                                log.info("orderStatus "+orderStatus);
                                log.info("message "+message);

                                if(!OrderStatus.NOTPAY.equals(orderStatus)){
                                   break;
                                }else{
                                    message = "订单暂未支付，手机端确认支付结果";
                                }

                            }
                            resultMap.put("orderStatus",orderStatus);
                            resultMap.put("message",message);
                            resultMap.put("amount",MathUtil.transForMoney(orderInfo.getTotalFee()));

                            return  ResultMessage.createSuccess(message,resultMap);


                        }else {
                                error = response.getSubMsg();
                                String buyer_logon_id = response.getBuyerLogonId();
                                orderInfo.setPayUserSign(buyer_logon_id);
                                orderInfo.setPayCode(authCode);
                                orderInfo.setPayType(PayType.SQR);
                                orderInfo.setStatus(-1);
                                orderInfo.setMessage(error);
                                this.orderInfoDao.updatePayInfo(orderInfo);

                                return ResultMessage.createFail(error);

                            }
                        }else {
                            error += response.getSubMsg();
                           return ResultMessage.createFail(error);

                    }

                    }else {
                        log.info("配置错误");
                        return ResultMessage.createFail("配置错误");
                    }

                }

            } else {
                return ResultMessage.createFail("订单不存在或订单已失效");
            }

        } catch (Exception e) {
            log.error("扫码支付异常", e);
        }


        return ResultMessage.createFail("支付失败");
    }
}
